# coding=utf-8
import math

import tornado.web

from CommonLib import *
from WorkManager import WorkManager
from database.models.Controller import Controller
from database.models.ControllerPoint import ControllerPoint
from database.models.DatabaseCommon import *
from database.models.PanelInstruct import PanelInstruct


def GetTypeID(d):
    if d == 1:
        iD = 3
    elif d == 0:
        iD = 1
    return iD


class InsDeviceHandler(tornado.web.RequestHandler):
    __metaclass__ = ABCMeta

    def UpdateValue(self, slaveID, value):
        s = Session()
        controller = s.query(Controller).with_for_update(read=False, nowait=False).filter_by(HardID=slaveID).all()
        if len(controller) != 1:
            return
        controller[0].Value = str(value)
        s.commit()

    def post(self):
        try:
            ojson = json.loads(self.request.body)
            slaveID = ojson['slaveID']
            _ = ojson['state']
            _ = ojson['tag']
            CheckJsonKeys(ojson, 'username', 'userpass')
            CheckAuth(ojson)
            alldata = ojson['all']
        except Exception as e:
            logging.warn('excption:' + str(e.message))
            return

        board_mark = alldata[0] << (8 * 3) | \
                     alldata[1] << (8 * 2) | \
                     alldata[2] << (8 * 1) | \
                     alldata[3]

        typeId = GetTypeID(alldata[4])

        hardid = slaveID[0] << 8 | slaveID[1]
        logging.debug('slaveid 0:%x,1:%x' % (slaveID[0], slaveID[1]))
        logging.debug('slave board mark:%s' % str(board_mark))
        logging.debug('use default slave id to insert table:' + str(hardid))

        if slaveID[0] != 0xf0 or slaveID[1] != 0x07:

            # 区分不同的从机类型
            if typeId == 3:
                # 按键板
                value = alldata[1] << 8 * 1 | alldata[0] << 8 * 0
                self.RunKeyNormal(slaveID[1] << 8 | slaveID[0], value)
                pass
            elif typeId == 1:
                # 控制板
                value = alldata[1] << 8 * 1 | alldata[0] << 8 * 0
                logging.debug('update board info:' + str(alldata))
                self.UpdateValue(slaveID[1] << 8 | slaveID[0], value)
            return

        s = Session()
        qcs = s.query(Controller).filter_by(tag=board_mark).all()
        if len(qcs) is not 0:
            return
            cap = int(alldata[7])
            typeId = GetTypeID(alldata[4])
            qcs[0].TypeID = typeId
            qcs[0].tag = str(board_mark)
            qcs[0].HardID = hardid
            qcs[0].capability = str(cap)
            #qcs[0].Name = ''
            s.commit()
            logging.info('board:%d reset to null name status' % qcs[0].id)
            return
        cap = int(alldata[7])
        logging.info('insert to contoller cap:' + str(cap))

        # 区分不同的从机类型
        if typeId == 3:
            # 按键板
            logging.info('insert to contoller type:' + str(typeId))
            ctl = Controller(TypeID=typeId, tag=str(board_mark), HardID=hardid, capability=str(cap))
            session = Session()
            session.add(ctl)
            session.commit()
            logging.info('insert controller point has %d cap' % cap)
            for i in range(1, cap + 1):
                point = ControllerPoint(ControllerID=ctl.id, PointIndex=i)
                session.add(point)
            session.commit()
            return

        elif typeId == 1:
            # 控制板
            logging.info('insert to contoller type:' + str(typeId))
            ctl = Controller(TypeID=typeId, tag=str(board_mark), HardID=hardid, capability=str(cap))
            session = Session()
            session.add(ctl)
            session.commit()
            logging.info('insert controller point has %d cap' % cap)
            for i in range(1, cap + 1):
                point = ControllerPoint(ControllerID=ctl.id, PointIndex=i)
                session.add(point)
            session.commit()
            return

    def RunKeyNormal(self, param, value):
        logging.debug("insert board run key normal")
        s = Session()
        controller = s.query(Controller).filter_by(HardID=param).all()
        if len(controller) != 1:
            logging.debug('query hardid retur 0,id:%d' % param)
            return
        ctlID = controller[0].id
        try:
            key = int(math.log(value)/math.log(2)) + 1
        except Exception as e:
            logging.warn('86 key board send 0 error:' + e.message)
            return
        logging.debug('start run normal ')
        inst = s.query(PanelInstruct).filter_by(ControllerID=ctlID, Key=key).all()
        if len(inst) != 1:
            return
        normalID = inst[0].NormalID
        CheckT = global_status.ai_ele_global_status.Get4NormalMap(str(normalID))
        if CheckT is None or len(CheckT) != 0:
            return
        aw = WorkManager(normalID)
        is_ok = aw.CheckError()
        if is_ok['code'] is not 0:
            logging.warn("thread work check is not ok")
            self.write(json.dumps(is_ok))
            return
        aw.Start()
        s.commit()
